home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 7 / BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso / Files / Bus / T-Z / TimeCalc.cpt / Time Calc / TimeCalc.srce < prev   
Text File  |  1990-03-02  |  8KB  |  369 lines

  1. {TimeCalc by Gre7g Luterman, Ballistic Grapeware}
  2.  
  3. {provisions: you may change my code (not comments), but I retain}
  4. {first credits, and postcards come to me. you may add to my}
  5. {code, but you may not sell it or what it becomes without my}
  6. {blessings in writing}
  7. program timecalc;
  8.  
  9.     const
  10.         maxhist = 50;
  11.  
  12.     var
  13.         thedialog: dialogptr;
  14.         dstorage: dialogrecord;
  15.         list: listhandle;
  16.         listrect: rect;
  17.         state: (first, add, sub, eq);
  18.         editing: (ehour, emin, esec);
  19.         current: record
  20.                 total: longint;
  21.                 hour, min, sec: integer;
  22.                 negative: boolean;
  23.             end;
  24.         memory: longint;
  25.  
  26.     procedure drawlist (dialog: dialogptr; item: integer);
  27.         var
  28.             thergn: rgnhandle;
  29.             therect: rect;
  30.     begin
  31.         thergn := newrgn;
  32.         with listrect do
  33.             setrect(therect, left - 1, top - 1, right + 16, bottom + 1);
  34.         with therect do
  35.             setrectrgn(thergn, left, top, right, bottom);
  36.         lupdate(thergn, list);
  37.         framerect(therect);
  38.     end;
  39.  
  40.     procedure callupdate;
  41.         function digit2 (num: integer): str255;
  42.             var
  43.                 temp: str255;
  44.         begin
  45.             numtostring(num, temp);
  46.             if num < 10 then
  47.                 digit2 := concat('0', temp)
  48.             else
  49.                 digit2 := temp;
  50.         end;
  51.         var
  52.             thecell: cell;
  53.             temp, scratch: str255;
  54.     begin
  55.         numtostring(current.hour, scratch);
  56.         if editing > ehour then
  57.             scratch := concat(scratch, ':', digit2(current.min));
  58.         if editing > emin then
  59.             scratch := concat(scratch, ':', digit2(current.sec));
  60.         thecell.h := 0;
  61.         thecell.v := pred(maxhist);
  62.         case state of
  63.             first: 
  64.                 scratch := concat(' ', scratch);
  65.             add: 
  66.                 scratch := concat('+', scratch);
  67.             sub: 
  68.                 scratch := concat('-', scratch);
  69.             eq: 
  70.                 scratch := concat('=', scratch);
  71.         end;
  72.         if current.negative then
  73.             scratch := concat(scratch, '  (-)');
  74.         lsetcell(pointer(succ(ord(@scratch))), length(scratch), thecell, list);
  75.         lscroll(0, maxhist, list);
  76.     end;
  77.  
  78.     procedure currentdoneprep;
  79.     begin
  80.         with current do begin
  81.                 if editing < esec then begin
  82.                         sec := min;
  83.                         min := hour;
  84.                         hour := 0;
  85.                     end;
  86.                 if editing < emin then begin
  87.                         sec := min;
  88.                         min := hour;
  89.                         hour := 0;
  90.                     end;
  91.                 editing := esec;
  92.                 total := sec + min * 60 + longint(hour) * 3600;
  93.             end;
  94.     end;
  95.  
  96.     procedure currentdone;
  97.         var
  98.             temp: integer;
  99.     begin
  100.         with current do begin
  101.                 negative := total < 0;
  102.                 total := abs(total);
  103.                 sec := total mod 60;
  104.                 min := (total div 60) mod 60;
  105.                 hour := total div 3600;
  106.             end;
  107.         callupdate;
  108.         if state = sub then
  109.             memory := memory - current.total
  110.         else
  111.             memory := memory + current.total;
  112.         temp := laddrow(1, maxhist, list);
  113.         ldelrow(1, 0, list);
  114.         current.hour := 0;
  115.         current.min := 0;
  116.         current.sec := 0;
  117.         current.negative := false;
  118.         editing := ehour;
  119.     end;
  120.  
  121.     procedure copy;
  122.         var
  123.             thecell: cell;
  124.             len: integer;
  125.             temp: array[0..127] of integer;
  126.     begin
  127.         thecell.h := 0;
  128.         thecell.v := pred(maxhist);
  129.         if zeroscrap = 0 then begin
  130.                 len := 256;
  131.                 lgetcell(@temp, len, thecell, list);
  132.                 if putscrap(pred(len), 'TEXT', pointer(succ(ord(@temp)))) <> 0 then
  133.                     sysbeep(1);
  134.             end
  135.         else
  136.             sysbeep(1);
  137.     end;
  138.  
  139.     procedure number (num: integer);
  140.     begin
  141.         with current do
  142.             case editing of
  143.                 ehour: 
  144.                     hour := (longint(hour) * 10 + num) mod 10000;
  145.                 emin: 
  146.                     min := (min * 10 + num) mod 100;
  147.                 esec: 
  148.                     sec := (sec * 10 + num) mod 100;
  149.             end;
  150.         callupdate;
  151.     end;
  152.  
  153.     procedure colon;
  154.     begin
  155.         if editing < esec then
  156.             editing := succ(editing)
  157.         else
  158.             sysbeep(1);
  159.         callupdate;
  160.     end;
  161.  
  162.     procedure paste;
  163.         type
  164.             data = packed array[0..32000] of char;
  165.             dataptr = ^data;
  166.             datahandle = ^dataptr;
  167.         var
  168.             err: boolean;
  169.             temp: datahandle;
  170.             i, len: integer;
  171.             offset: longint;
  172.     begin
  173.         err := false;
  174.         temp := datahandle(newhandle(0));
  175.         len := getscrap(handle(temp), 'TEXT', offset);
  176.         writeln(len);
  177.         if (len < 0) or (len > 20) then
  178.             sysbeep(1)
  179.         else begin
  180.                 current.hour := 0;
  181.                 current.min := 0;
  182.                 current.sec := 0;
  183.                 current.negative := false;
  184.                 editing := ehour;
  185.                 for i := 0 to pred(len) do begin
  186.                         writeln(i, ',', temp^^[i]);
  187.                         case temp^^[i] of
  188.                             '0'..'9': 
  189.                                 number(ord(temp^^[i]) - 48);
  190.                             ':', '.': 
  191.                                 colon;
  192.                             '-': 
  193.                                 current.negative := true;
  194.                             otherwise
  195.                                 err := true;
  196.                         end;
  197.                     end;
  198.                 if temp <> nil then
  199.                     disposhandle(handle(temp));
  200.                 if err then
  201.                     sysbeep(1);
  202.                 callupdate;
  203.             end;
  204.     end;
  205.  
  206.     procedure plus;
  207.     begin
  208.         currentdoneprep;
  209.         currentdone;
  210.         state := add;
  211.         callupdate;
  212.     end;
  213.  
  214.     procedure minus;
  215.     begin
  216.         currentdoneprep;
  217.         currentdone;
  218.         state := sub;
  219.         callupdate;
  220.     end;
  221.  
  222.     procedure equals;
  223.     begin
  224.         currentdoneprep;
  225.         currentdone;
  226.         state := eq;
  227.         current.total := memory;
  228.         editing := esec;
  229.         currentdone;
  230.         state := first;
  231.         callupdate;
  232.         memory := 0;
  233.     end;
  234.  
  235.     procedure liststuff (event: eventrecord);
  236.         var
  237.             temp: boolean;
  238.             newdialog: dialogptr;
  239.             thergn: rgnhandle;
  240.             therect: rect;
  241.     begin
  242.         setport(thedialog);
  243.         globaltolocal(event.where);
  244.         if event.where.h > listrect.right then
  245.             temp := lclick(event.where, event.modifiers, list)
  246.         else begin
  247.                 newdialog := getnewdialog(129, nil, pointer(-1));
  248.                 thergn := newrgn;
  249.                 with newdialog^.portrect do
  250.                     setrect(therect, left - 1, top - 1, right + 16, bottom + 1);
  251.                 with therect do
  252.                     setrectrgn(thergn, left, top, right, bottom);
  253.                 updtdialog(newdialog, thergn);
  254.                 while stilldown do
  255.                     ;
  256.                 repeat
  257.                 until getnextevent(mdownmask, event);
  258.                 disposdialog(newdialog);
  259.             end;
  260.     end;
  261.  
  262. {Main Program}
  263.     var
  264.         a: char;
  265.         i, j, k, item: integer;
  266.         r: rect;
  267.         where, cell, csize: point;
  268.         databounds: rect;
  269.         event: eventrecord;
  270.         temp: handle;
  271.         done, trapit: boolean;
  272. begin
  273.     done := false;
  274.     state := first;
  275.     editing := ehour;
  276.     memory := 0;
  277.     current.hour := 0;
  278.     current.min := 0;
  279.     current.sec := 0;
  280.     current.negative := false;
  281.     thedialog := getnewdialog(128, @dstorage, pointer(-1));
  282.     getditem(thedialog, 18, item, temp, listrect);
  283.     setditem(thedialog, 18, item, @drawlist, listrect);
  284.     setrect(databounds, 0, 0, 1, maxhist);
  285.     csize.h := listrect.right - listrect.left - 15;
  286.     csize.v := 16;
  287.     listrect.right := listrect.right - 17;
  288.     list := lnew(listrect, databounds, csize, 0, thedialog, false, false, false, true);
  289.     callupdate;
  290.     lscroll(0, maxhist, list);
  291.     selectwindow(thedialog);
  292.     list^^.listflags := 0;
  293.     list^^.selflags := lonlyone;
  294.     repeat
  295.         initcursor;
  296.         repeat
  297.             systemtask;
  298.         until getnextevent(everyevent, event);
  299.         item := bitand(event.message, charcodemask);
  300.         trapit := false;
  301.         if ((event.what = keydown) or (event.what = autokey)) and (bitand(event.modifiers, cmdkey + optionkey) = 0) then
  302.             case item of
  303.                 48..57: 
  304.                     begin
  305.                         item := item - ord('0') + 4;
  306.                         trapit := true;
  307.                     end;
  308.                 46, 58: 
  309.                     begin
  310.                         item := 14;
  311.                         trapit := true;
  312.                     end;
  313.                 43: 
  314.                     begin
  315.                         item := 15;
  316.                         trapit := true;
  317.                     end;
  318.                 45: 
  319.                     begin
  320.                         item := 16;
  321.                         trapit := true;
  322.                     end;
  323.                 3, 13, 61: 
  324.                     begin
  325.                         item := 17;
  326.                         trapit := true;
  327.                     end;
  328.                 otherwise
  329.                     ;
  330.             end;
  331.         if ((event.what = keydown) or (event.what = autokey)) and (bitand(event.modifiers, cmdkey + optionkey) = cmdkey) then
  332.             case item of
  333.                 99: 
  334.                     copy;
  335.                 118: 
  336.                     paste;
  337.                 113: 
  338.                     done := true;
  339.                 otherwise
  340.                     ;
  341.             end;
  342.         if not trapit then
  343.             if isdialogevent(event) then
  344.                 if dialogselect(event, thedialog, item) then
  345.                     trapit := true;
  346.         if trapit then
  347.             case item of        {QCP0123456789:+-=L}
  348.                 1: 
  349.                     done := true;
  350.                 2: 
  351.                     copy;
  352.                 3: 
  353.                     paste;
  354.                 4..13: 
  355.                     number(item - 4);
  356.                 14: 
  357.                     colon;
  358.                 15: 
  359.                     plus;
  360.                 16: 
  361.                     minus;
  362.                 17: 
  363.                     equals;
  364.                 18: 
  365.                     liststuff(event);
  366.             end;
  367.     until done;
  368.     disposdialog(thedialog);
  369. end.